import sys
import traceback
import json
from sqlalchemy.orm import Session
from app.common.enums import ErrTypes, OrderStatus
from app.common.exceptions import GenericException
from app import utils
from app.utils.cache_util import CacheUtil
from app import services, schemas
from app.models import PayOrder,Factor, FactorFee, OrderNotice
from app import conf

import logging
logger = logging.getLogger(__name__)

ACCOUNT_CENTER_URL = conf.SERVCIE_URLS.get('account-center') 

JOB_PROCESS_CENTER_URL = conf.SERVCIE_URLS.get('job-process-center') 
JOB_DISPATCH_URI = '/job/dispatch'
JOB_API_URL = conf.SERVCIE_URLS.get('job-api') 
JOB_CALLAPI_URL = f'{JOB_API_URL}/job/callApi'
#XP_JOB_ID = 7
#XP_JOB_NAME = "profit.init_order_profit"


def order_init_after_task(db: Session, new_order: PayOrder, params: dict, factor: Factor, 
                          factor_fee: FactorFee, fee_mode, trans_fee, pay_channel_code):
        try:
            logger.info('==> order_init_after_task')
            #cache = CacheUtil(db)
            #cache.push_order_no(new_order.order_no)
            #if params.get('notify_url'):
            #    init_notice(db, new_order, params=params)
            # 跟踪订单状态
            trace_order_status(order_no=new_order.order_no)
        except GenericException as err:
            logger.error(err.message)
            logger.info('error data: %s' % err.data)
            #raise GenericException(err.error_type, message=err.message, data=err.data)
        except Exception as err:
            logger.error('订单初始后续任务失败')
            exc_type, exc_value, exc_obj = sys.exc_info()
            traceback.print_exception(exc_type,exc_value,exc_obj,limit=3,file=sys.stdout)
            #raise GenericException(ErrTypes.chn_trans_error)

def order_init_after_task_v1_bak(db: Session, new_order: PayOrder, params: dict, factor: Factor, 
                          factor_fee: FactorFee, fee_mode, trans_fee, pay_channel_code):
        try:
            logger.info('==> order_init_after_task')
            cache = CacheUtil(db)
            cache.push_order_no(new_order.order_no)
            #if params.get('notify_url'):
            #    init_notice(db, new_order, params=params)
            if new_order.status not in (2, 9):
                # 订单状态非失败或取消
                init_profit(db=db, new_order=new_order, factor=factor,
                                            factor_fee=factor_fee,
                                            fee_mode=fee_mode, trans_fee=trans_fee,
                                            pay_channel_code=pay_channel_code)
        except GenericException as err:
            logger.error(err.message)
            raise GenericException(err.error_type, message=err.message, data=err.data)
        except Exception as err:
            logger.error('订单初始后续任务失败')
            exc_type, exc_value, exc_obj = sys.exc_info()
            traceback.print_exception(exc_type,exc_value,exc_obj,limit=3,file=sys.stdout)
            raise GenericException(ErrTypes.chn_trans_error)


def init_notice(db: Session, new_order: PayOrder, params: dict):
        try:
            logger.info('>> 初始化通知记录')
            services.order.add_order_notice(db, new_order=new_order, params=params)
        except GenericException as err:
            logger.error(err.message)
            raise GenericException(err.error_type, message=err.message, data=err.data)
        except Exception as err:
            logger.error('初始化通知记录失败')
            exc_type, exc_value, exc_obj = sys.exc_info()
            traceback.print_exception(exc_type,exc_value,exc_obj,limit=3,file=sys.stdout)
            raise GenericException(ErrTypes.chn_trans_error)
        

def trace_order_status(order_no: str):
    logger.info('>> 跟踪订单状态')
    job_param = {
        "version": "1.0",
        "name": "trans.trace_order_status",
        "args": [],
        "kwargs": {
            "order_no": order_no
        },
        "remark": "订单跟踪"
    }
    payload = {
        "apiName": "runJob",
        "jobId": 8,
        "delayMS": 5000,
        "jobParam": json.dumps(job_param)
    }
    res = utils.request_service_api(JOB_API_URL, '/job/callApi', payload)
    logger.info(f'任务中心返回: {res}')
    if not res.get('code') == 200:
        raise GenericException(ErrTypes.job_resp_error)

def init_profit(db: Session, new_order: PayOrder, factor: Factor, factor_fee: FactorFee,
                          fee_mode, trans_fee, pay_channel_code):
        logger.info('>> 初始化分润明细')
        try:
            #profit_amount = 0
            chn_cost_amount = 0
            factor_profit = 0
            factor_cost_amount = 0
            trans_amount = new_order.amount  
            db_chn_fee = services.get_channel_fee(db, pay_channel_code, fee_mode)
            
            if fee_mode == 1:
                chn_cost_amount = db_chn_fee.fee_value
                factor_cost_amount = factor_fee.fee_value
                factor_profit = trans_fee - factor_cost_amount
            elif fee_mode == 2:
                chn_cost_amount = new_order.amount * db_chn_fee.fee_value
                factor_cost_amount = factor_fee.fee_value * trans_amount
                factor_profit = trans_fee - factor_cost_amount
            else:
                raise GenericException(ErrTypes.fee_unsupported_mode)
            
            logger.debug(f'分润金额: {factor_profit}, 通道成本: {chn_cost_amount}')
            profit_detail = schemas.NewProfitDetail(
                order_no=new_order.order_no,
                factor_no=factor.factor_no,
                factor_name=factor.factor_name,
                merc_no=new_order.merc_no,
                factor_lvl=factor.factor_lvl,
                trans_amount=trans_amount,
                trans_fee=trans_fee,
                profit_amount=factor_profit,
                cost_amount=factor_cost_amount,
                fee_mode=fee_mode,
                chn_cost_amount=chn_cost_amount,
                order_type=new_order.order_type,
                pay_type=new_order.pay_type,
                trans_time=new_order.create_time.timestamp(),
                credit_status=0
            )
            #json_compatible_data = jsonable_encoder(profit_detail)
            #res = utils.request_service_api(ACCOUNT_CENTER_URL, '/v1/profit/init_order_profit',  profit_detail.model_dump())
            #logger.info(f'账户中心返回: {res}')
            #if not res.get('code') == '000000':
            job_param = {
                "version": "1.0",
                "name": "profit.init_order_profit",
                "args": [],
                "kwargs": {
                    "new_profit": profit_detail.model_dump()
                },
                "remark": "simple test"
            }
            payload = {
                "apiName": "runJob",
                "jobId": 7,
                "delayMS": 3000,
                "jobParam": json.dumps(job_param)
            }
            res = utils.request_service_api(JOB_CALLAPI_URL, payload)
            logger.info(f'任务中心返回: {res}')
            if not res.get('code') == 200:
                raise GenericException(ErrTypes.profit_init_error)
        except GenericException as err:
            logger.error(err.message)
            raise GenericException(err.error_type, message=err.message, data=err.data)
        except Exception as err:
            logger.error('初始化分润失败')
            exc_type, exc_value, exc_obj = sys.exc_info()
            traceback.print_exception(exc_type,exc_value,exc_obj,limit=3,file=sys.stdout)
            raise GenericException(ErrTypes.chn_trans_error)